<?php
namespace GrouppaGroup;

require_once 'Controller.php';
require_once 'User.php';
require_once 'MessageFromServer.php';

class UserAccountController extends Controller
{

    /**
     * receives a message from an application (override from controller)
     * @param MessageFromApp $message
     */
    public function receiveMessage(MessageFromApp $message)
    {
        //CHECK: handle received message
        if (!parent::checkAccess($message)) {
            $errorMessage = new ErrorMessage(parent::$accessRejectReason, 'error',
                'UserAccount', $message->id);

            return;
        }

        if ($message->task) {
            switch ($message->task) {
                case 'getProfile':
                    $this->getProfile($message);
                    break;
                case 'changeProfile':
                    $this->changeProfile($message);
                    break;
                default:
                    self::unknownTask($message, 'UserAccount');
            }
        }
    }

    /*
    ****************** Section: functions available to call for the applications
    */

    /**
     * sends back to the server all the information about the user
     * @param $message MessageFromApp that called this function
     * with userName parameter
     */
    public function getProfile(MessageFromApp $message)
    {

        //CHECK: retrieve and return all topics for current active group
        if (!$message->serializedArguments || !is_a($message->serializedArguments,
            'stdClass')) {
            throw new \Exception('UserAccountController::getProfile error: message didn\'t contain proper json object');
        }
        $args = $message->serializedArguments;
        if (!property_exists($args, 'userName')) {
            throw new \Exception('UserAccountController::getProfile error: message parameters didn\'t contain ' .
                'user name');
        }

        $userName = $args->userName;
        if (!is_string($userName)) {
            throw new \Exception('UserAccountController::getProfile error: user name is not a string');
        }

        $db = Db::getInstance();

        return $this->sendUserInformation($db,$userName,$message,true);
    }

    private function sendUserInformation($db, $userName,$message,$success,$firstStage=null,$secondStage=null)
    {
        //getting password, email and other information about the user
        $result = $db->sendQuery('SELECT `password`, `email`, `key`,`value`, users.id_user FROM users LEFT JOIN user_informations  ON users.id_user = user_informations.id_user WHERE  '
                .'users.user_name = "'.$userName.'";');

        $info = array();
        $row;
        $n = $result->num_rows;
        for ($i = 0; $i < $n; $i++) {
            $row = $result->fetch_row();
            if ($row[2] && $row[3]) {
                $info[$row[2]] = $row[3];
            }
        }
        $reason='';
        if ($n == 0) {
            $success = false;
            $reason = 'Couldn\'t find a "'.$userName.'" user name';
        }

        $serializedArguments = json_encode(array(
            'succeeded' => $success,
            'extra' => $info,
            'username' => $userName,
            'pin'=> $row[0],
            'email'=> $row[1],
            'userId'=> $row[4],
            'reason'=> $reason,
            'first stage' => $firstStage,
            'second stage'=> $secondStage
        ));

        $responseMessage = new MessageFromServer($serializedArguments, 'UserAccount', $message->
            messageType, $message->id);
        $responseMessage->toController="LoginView";
        ApplicationTCPConnection::sendMessage($responseMessage);

        return $n;

    }
    /**
     * changes all the information about the user
     * @param $message MessageFromApp that called this function
     * with userId parameter, the following parameters must be added if a change is desired:
     * userName
     * pin
     * email
     * other keys (telephone, extra info etc.)
     */
    public function changeProfile(MessageFromApp $message)
    {

        //CHECK: retrieve and return all topics for current active group
        if (!$message->serializedArguments || !is_a($message->serializedArguments,
            'stdClass')) {
            throw new \Exception('UserAccountController::changeProfile error: message didn\'t contain proper json object');
        }
        $args = $message->serializedArguments;
        if (!property_exists($args, 'userId')) {
            throw new \Exception('UserAccountController::changeProfile error: message parameters didn\'t contain ' .
                'user id');
        }

        $userName = $message->from;
        $userId = $args->userId;
        if (!is_numeric($userId)) {
            throw new \Exception('UserAccountController::changeProfile error: user id is not a number');
        }

        $db = Db::getInstance();

        $mainQueryUpdates = '';
        if (property_exists($args,'userName') && is_string($args->userName)) {
            $mainQueryUpdates .= ',user_name = "'.$args->userName.'"';
            $userName = $args->userName;
        }

        if (property_exists($args,'pin') && is_string($args->pin)) {
            $mainQueryUpdates .= ',password = "'.$args->pin.'"';
        }

        if (property_exists($args,'email') && is_string($args->email)) {
            $mainQueryUpdates .= ',email = "'.$args->email.'"';
        }

        $errors = '';
        $firstStage = true;
        $mainQuery;
        if ($mainQueryUpdates != '') {
            $mainQueryUpdates = substr($mainQueryUpdates,1);
            $mainQuery = 'UPDATE users SET '.$mainQueryUpdates.' WHERE id_user='.$userId;
            $firstStage = $db->sendUpdateQuery($mainQuery);
        }

        $extraInfo = array();
        foreach ($args as $key=>$value) {
            switch ($key) {
                case 'user_name':
                case 'userName':
                case 'pin':
                case 'password':
                case 'email':
                case 'userId':
                    break;
                default:
                    $extraInfo[$key] = $value;
                    break;
            }
        }
        $secondStage = true;
        $extraQuery;
        if (count($extraInfo) > 0) {
            $extraQuery = 'REPLACE INTO user_informations (id_user,`key`,`value`) VALUES ';
            $first = true;
            foreach ($extraInfo as $key => $value) {
                $key = $db->escape($key);
                $value = $db->escape($value);
                if (!$first) {
                    $extraQuery .=',';
                } else {
                    $first = false;
                }
                $extraQuery .= "($userId,\"$key\",\"$value\")";
            }
            $secondStage = $db->sendReplaceQuery($extraQuery);
        }

        return $this->sendUserInformation($db,$userName,$message,true,$firstStage,$secondStage);
    }

}
